
#include "auth.h"
#include "hlog.h"
#include "hstring.h"
#include "md5.h"

namespace zx {

SINGLETON_IMPL(Auth)

Auth::Auth() {
    m_czgw_token      = AUTH_CZGW_TOKEN;
    this->m_token_dep = get_current_date();
    hlogi("update token:%s", this->m_token_dep.c_str());
}

Auth::~Auth() {
}

std::string Auth::get_current_date() {
    auto now           = std::chrono::system_clock::now();
    std::time_t now_c  = std::chrono::system_clock::to_time_t(now);
    std::tm* localTime = std::localtime(&now_c);
    char dateBuffer[20];
    std::strftime(dateBuffer, sizeof(dateBuffer), "%Y", localTime);
    return std::string(dateBuffer);
}

void Auth::update_token(hv::EventLoopPtr loop) {
    // TODO暂不更新Token
    return;

    loop->setInterval(TIME_INTERVAL, [this](hv::TimerID id) {
        this->m_token_dep = get_current_date();
        hlogi("update token:%s", this->m_token_dep.c_str());
    });
}

std::string Auth::gen_token(std::string user) {
    if (user.empty()) return std::string();
    char ret[33] = {0};
    // std::string token_dep = user;
    std::string token_dep = user + m_token_dep;
    hv_md5_hex((unsigned char*)token_dep.c_str(), token_dep.size(), ret, sizeof(ret));
    return ret;
}

// 只有admin才有注册权限
bool Auth::user_register(std::string user, std::string password) {
    if (user.empty() || password.empty()) return false;
    std::string username = "user:" + user;
    if (MiscStorageHandler->kvget(username).empty()) {
        MiscStorageHandler->kvset(username, password);
        return true;
    }
    return false;
}

bool Auth::user_modify(std::string user, std::string password) {
    if (user.empty() || password.empty()) return false;
    std::string username = "user:" + user;
    if (!MiscStorageHandler->kvget(username).empty()) {
        MiscStorageHandler->kvset(username, password);
        return true;
    }
    return false;
}

std::vector<std::string> Auth::user_get(void) {
    auto users = MiscStorageHandler->kv_keys("user:");
    std::vector<std::string> vec;
    for (auto it = users.begin(); it != users.end(); ++it) {
        vec.emplace_back(it->first);
        // std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
    }
    return vec;
}

bool Auth::user_delete(std::string user) {
    std::string username = "user:" + user;
    MiscStorageHandler->kvdel(username);
    return true;
}

bool Auth::login(std::string user, std::string password) {
    std::string username = "user:" + user;
    if (password == MiscStorageHandler->kvget(username)) {
        auto it = m_logins.find(user);
        if (it == m_logins.end()) {
            m_logins[user] = password;
            return true;
        }
    }
    return false;
}

bool Auth::logout(std::string user) {
    auto it = m_logins.find(user);
    if (it != m_logins.end()) {
        m_logins.erase(user);
        return true;
    }
    return false;
}

bool Auth::is_admin_login(std::string token) {
    return gen_token("admin") == token;
}

bool Auth::is_user_login(std::string token) {
    for (const auto& pair : m_logins) {
        if (gen_token(pair.first) == token) {
            return true;
        }
    }
    return false;
}
bool Auth::is_czgw_login(std::string token) {
    return m_czgw_token == token;
}

}  // namespace zx
